/***************************************************************************************
* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
* Copyright (c) 2020-2021 Peng Cheng Laboratory
*
* XiangShan is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/
/*
import "DPI-C" function void ram_write_helper
(
  input  longint    wIdx,
  input  longint    wdata,
  input  longint    wmask,
  input  bit        wen
);

import "DPI-C" function longint ram_read_helper
(
  input  bit        en,
  input  longint    rIdx
);
*/
module RAMHelper_1w2r(
  input         clk,

  input  [63:0] inst_addr,
  input         inst_ena,
  output [31:0] inst,
  // Data port
  input         en,
  input  [63:0] rd_addr,
  output [63:0] rdata,
  input  [63:0] wr_addr,
  input  [63:0] wdata,
  input  [63:0] wmask,
  input         wen
);

  wire [63:0] inst_2 = ram_read_helper(inst_ena, {3'b000,(inst_addr-64'h0000_0000_8000_0000)>>3} );
  assign inst = inst_addr[2] ? inst_2[63:32] : inst_2[31:0];

  assign rdata = ram_read_helper(en, {3'b000,(ram_addr-64'h0000_0000_8000_0000)>>3});

  always @(posedge clk) begin
    ram_write_helper((ram_addr-64'h0000_0000_8000_0000)>>3, wdata, wmask, wen && en);
  end

endmodule

module ram_2r1w(
    input         clk,

    input         imem_en,
    input  [63:0] imem_addr,
    output [63:0] imem_data,

    input         dmem_en,
    input  [63:0] dmem_addr,
    output [63:0] dmem_rdata,
    input  [63:0] dmem_wdata,
    input  [63:0] dmem_wmask,
    input         dmem_wen

);
  wire [63:0] imem_data_0 = ram_read_helper(imem_en, {3'b000, (imem_addr - 64'h0000_0000_8000_0000) >> 3});

  assign imem_data = {32'b0000_0000_0000_0000, (imem_addr[2] ? imem_data_0[63:32] : imem_data_0[31:0])};

  assign dmem_rdata = ram_read_helper(dmem_en, {3'b000, (dmem_addr-64'h0000_0000_8000_0000) >> 3});

  always @(posedge clk) begin
    ram_write_helper((dmem_addr - 64'h0000_0000_8000_0000) >> 3, dmem_wdata, dmem_wmask, dmem_en & dmem_wen);
  end

endmodule